/**
 * @author Administrator
 * 控制一个链条，就像《flow》里的虫子
 * 是一连串的model,后面的会尽量去移动到以上一个节点为圆心，指定半径的，angle=_yrotation+180的指定位置的位置
 * 
 * 注意这个又算距离又算位置，有些耗资源啊
 * 
 * 注意K1,K2小于0的时候还不能正常工作 
 */
package kgame5.keff.dc {
import kgame5.k3d.core.math.Vector3D;
import kgame5.k3d.core.obj3d.node3d.Node3D;
import kgame5.kmath.MathDG;
import kgame5.kutil.*;

public class DragonChain {
	//_________________Property_____________________
	private var 
		K1:Number,//节点的弹簧系数,距离的
		K2:Number;//节点的弹簧系数,角度的
	private var nodeDistance:Number;//两个节点之间的距离
	private var aNode:Array;//是一个array
	
	//_________________Method_____________________
	public function DragonChain(p_nodeDistance:Number=16,k_dis:Number=3,k_angle:Number=3){
		nodeDistance=p_nodeDistance;
		K1=k_dis;//距离的弹簧系数,小于0为是匀速运动,等于0就是角度直接变到那里
		K2=k_angle;//角度的弹簧系数,小于0为是匀速运动
		aNode=new Array();
	}
	
	public function addNode(md:Node3D){
		aNode.push(md);
		
		var i:int=aNode.length-1;
		if(aNode.length!=1){
			//2
			var preNode:Node3D=Node3D(aNode[i-1]);
			var node:Node3D=Node3D(aNode[i]);
			
			//计算好自己当前的位置,注意这里的y也是自己的朝向
			//1,自己的角度
			node.rotY=preNode.rotY;
			
			//2,两个节点的当前的距离
			var dis:Number=this.nodeDistance;
			
			//3,计算自己的位置
			var rad:Number=(node.rotY+180)*MathDG.DTR;
			var x:Number=Math.sin(rad)*dis;
			var z:Number=Math.cos(rad)*dis;
			
			node.x=preNode.x+x;
			//node.v3d_p.y=preNode.v3d_p.y;
			node.z=preNode.z+z;
		}
	}
	//取得指定编号的节点
	public function getNodeAt(idx:int):Node3D{
		return Node3D(aNode[idx]);
	}
	
	//更新位置，并不一定要每真都更新
	public function update(startIdx:int=0){
		
		var i:int;
		var len:int=aNode.length;
		for(i=startIdx;i<len;i++){
			//头一个不会跟随上一个动的
			if(i==0){
				continue;
			}
			//2
			var preNode:Node3D=Node3D(aNode[i-1]);
			var node:Node3D=Node3D(aNode[i]);
			
			//计算好自己当前的位置
			//1,自己的角度
			if(K2<0){
				node.rotY=MathDG.W(node.rotY,preNode.rotY,-K2);
			}else if(K2>0){
				node.rotY=MathDG.Spring3(node.rotY,preNode.rotY,K2);
			}else{
				node.rotY=preNode.rotY;
			}
			//2,两个节点的当前的距离
			var dis:Number=Vector3D.SGetDistance(preNode.ti.hardVO.v3d_p,node.ti.hardVO.v3d_p);
			if(K1<0){
				dis=MathDG.W(dis,this.nodeDistance,-K1);
			}else if(K1>0){
				dis=MathDG.Spring3(dis,this.nodeDistance,K1);
			}else{
				dis=this.nodeDistance;
			}
			
			//3,计算自己的位置
			var rad:Number=(node.rotY+180)*MathDG.DTR;
			var x:Number=Math.sin(rad)*dis;
			var z:Number=Math.cos(rad)*dis;
			
			node.x=preNode.x+x;
			//node.v3d_p.y=preNode.v3d_p.y;
			node.z=preNode.z+z;
		}
	}
	
	
	//控制测试
	public function Test(){
		var md:Node3D=getNodeAt(0);
		if(KKey.isDown_LEFT) {
			
			md.rotY-=10;
			
			//T.p(md._yrotation);
		}else if(KKey.isDown_RIGHT){
			md.rotY+=10;
			
			//T.p(md._yrotation);
		}
		
		var speed:Number=0;
		if(KKey.isDown_UP){	
			speed=40;
		}else if(KKey.isDown_DOWN){
			speed=-40;
		}
		var rad:Number=MathDG.DTR*md.rotY;
		var vx:Number=Math.sin(rad)*speed;
		var vz:Number=Math.cos(rad)*speed;
		
		md.x+=vx;
		md.z+=vz;
		//T.p("!!"+md._yrotation+" "+md.preYRotation);
		this.update(0); 
	}
	
	/*
	if(bAutoSway){//如果需要自动摆动，则摆动
			this.updateAutoSway();
			
			getHead().v3d_r.y+=this.autoSway_angle;
		}
		
		update();
		//千万注意用完了autoSway还要减回去呢把这个
		if(bAutoSway){//如果需要自动摆动，则摆动
			getHead().v3d_r.y-=this.autoSway_angle;
		}
	//*/
	/////////////
	//自动摆尾的功能
	private var bAutoSway:Boolean=false;
	
	private var 
		AutoSway_minAngle:Number,
		AutoSway_maxAngle:Number,
		AutoSway_angleAcc:Number,
		
		autoSway_angle:Number,
		autoSway_angleSpeed:Number,
		autoSway_angleAcc:Number;
		
	public function startAutoSway(minAngle:Number,maxAngle:Number,angleAcc:Number){
		AutoSway_minAngle=minAngle;
		AutoSway_maxAngle=maxAngle;
		autoSway_angle=0;
		
		autoSway_angleSpeed=0;
		AutoSway_angleAcc=angleAcc;
		autoSway_angleAcc=AutoSway_angleAcc;
		
		bAutoSway=true;
	}
	public function stopAutoSway(){
		bAutoSway=false;
		autoSway_angle=0;
	}
	private function updateAutoSway(){
		autoSway_angleSpeed+=autoSway_angleAcc;
		autoSway_angle+=autoSway_angleSpeed;
		
		if(autoSway_angle<AutoSway_minAngle){
			autoSway_angleAcc=AutoSway_angleAcc;
			autoSway_angleSpeed=0;
		}else if(autoSway_angle>AutoSway_maxAngle){
			autoSway_angleAcc=-AutoSway_angleAcc;
			autoSway_angleSpeed=0;
		}
	}
}//end of class
}